The Impact of Firearm Availability on Violence and Safety Across the United States

Group number 24

Names of students:

Tamar Gurfinkel
Naama Sapir
Liav Shamama

From:
Link to Kaggle: https://www.kaggle.com/datasets/williecosta/firearm-suicide-rates-1949-2020?resource=download
Kaggle sources: CDC – Centers for Disease Control and Prevention,
WISQARS – Web-based Injury Statistics Query and Reporting System,
NVSS – National Vital Statistics System


No description has been provided for this image

מבוא תיאורטי

מהו מדד FSS ולמה הוא חשוב?

מדד ה־FSS (Firearm Suicide Share) הוא מדד עקיף להערכת שיעור החזקת נשק חם בבתים. הוא מחושב על־ידי חלוקת מספר מקרי ההתאבדות שבוצעו באמצעות נשק חם בסך כל מקרי ההתאבדות במדינה ובשנה מסוימת.

לדוגמה: אם התרחשו במדינה מסוימת 100 מקרי התאבדות, ומתוכם 40 בוצעו באמצעות נשק חם – ערך המדד יהיה 0.4 (כלומר, 40%).

המשמעות של ערך גבוה במדד FSS היא ששיעור ההתאבדויות שבוצעו בנשק חם מתוך כלל ההתאבדויות במדינה הוא גבוה יותר. במחקר של Kang & Rasich (2023) נמצא כי ערך זה נמצא במתאם גבוה עם שיעורי החזקת נשק כפי שנמדדו בסקרים ידועים – ולכן הוא יכול לשמש כאומדן עקיף ואמין להערכת זמינות נשק במדינה לאורך השנים.

זהו מדד מקובל במחקר בתחום, מאחר שהוא מבוסס על נתונים רשמיים ואובייקטיביים – ולא על סקרים העלולים להיות מושפעים מהטיות פוליטיות, חברתיות או דיווחים עצמאיים.


סקירה תיאורטית – על מה התבסס הניתוח בפרויקט?

לצורך הניתוח בפרויקט זה נעזרנו במאמרם של Kang & Rasich (2023), המציג מאגר נתונים היסטורי נרחב הכולל את מדד ה־FSS לכל מדינה בארה"ב בין השנים 1949–2020.

המאמר מציג את מדד ה־FSS כאומדן עקיף, מבוסס־נתונים, להערכת שיעור החזקת נשק חם בבתים – ומציע להשתמש בו ככלי עזר במחקרים אפידמיולוגיים, חברתיים ופוליטיים לצורך הבנת מגמות של זמינות נשק.

בפרויקט שלנו נעשה שימוש במדד זה כדי לבחון קשרים אפשריים בין זמינות נשק חם (FSS) לבין שיעורי התאבדויות ורצח לאורך זמן ובחתכים גאוגרפיים – תוך שימוש בדאטה המקורית שפורסמה על־ידי החוקרים במסגרת המאמר.

📎 לצפייה במאמר המלא:
https://doi.org/10.1016/j.dib.2023.109548

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
from sklearn.linear_model import LinearRegression
import plotly.express as px
from matplotlib.colors import Normalize, to_hex
import matplotlib as mpl
import statsmodels.api as sm
from scipy.stats import linregress

פתיחה והיכרות עם הנתונים

  • טעינת הנתונים ובחינת המבנה הראשוני של המסמך
  • זיהוי סוגי המשתנים וסיווגם
  • טיפול בערכים חסרים והמרת טיפוסים
  • יצירת גרף מגמה של מדד ה־FSS לאורך זמן
  • הצגת מפת קורלציה (Heatmap) להבנת הקשרים בין משתנים
url = 'https://raw.githubusercontent.com/TamarGurfinkel/project_1/refs/heads/main/%D7%93%D7%90%D7%98%D7%94%20%D7%9C%D7%A4%D7%A8%D7%95%D7%99%D7%A7%D7%98.csv'
df = pd.read_csv(url)
df.head(10)
year state division total_population fss homicide_rate firearm_homicide_rate nonfirearm_homicide_rate firearm_suicides total_suicides firearm_homicides nonfirearm_homicides total_homicides white_fss nonwhite_fss nextyearfss nextyearnonwhitefss nextyearwhitefss
0 1949 Alabama East South Central 3004000.0 0.717949 14.28095872 7.822902796 6.458055925 140 195 235.0 194.0 429 0.708571 0.482655 0.688995 0.807692 0.672131
1 1949 Arizona Mountain 726000.0 0.575000 5.64738292 3.168044077 2.479338843 46 80 23.0 18.0 41 0.583333 0.800000 0.589474 0.625000 0.586207
2 1949 Arkansas West South Central 1835000.0 0.671053 7.901907357 4.141689373 3.760217984 102 152 76.0 69.0 145 0.664336 0.500000 0.644444 0.750000 0.632812
3 1949 California Pacific 10499000.0 0.382623 4.61948757 1.857319745 2.762167826 709 1853 195.0 290.0 485 0.382187 0.777778 0.378732 0.367647 0.379142
4 1949 Colorado Mountain 1249000.0 0.551570 5.044035228 3.442754203 1.601281025 123 223 43.0 20.0 63 0.559633 0.392405 0.462687 0.000000 0.467337
5 1949 Connecticut New England 2006000.0 0.186441 1.794616152 0.697906281 1.09670987 44 236 14.0 22.0 36 0.188841 0.200000 0.254237 0.000000 0.235294
6 1949 Delaware South Atlantic 319000.0 0.268293 7.836990596 5.642633229 2.194357367 11 41 18.0 7.0 25 0.250000 0.000000 0.435897 1.000000 0.421053
7 1949 District of Columbia South Atlantic 839000.0 0.326923 10.60786651 4.052443385 6.555423123 34 104 34.0 55.0 89 0.337209 0.333333 0.271739 0.384615 0.253165
8 1949 Florida South Atlantic 2679000.0 0.504249 11.7581187 5.48712206 6.270996641 178 353 147.0 168.0 315 0.513353 0.277778 0.518987 0.578947 0.515152
9 1949 Georgia South Atlantic 3360000.0 0.713805 12.70833333 7.797619048 4.910714286 212 297 262.0 165.0 427 0.714815 0.312500 0.674825 0.722222 0.668000
df.shape
(3651, 18)
df.columns
Index(['year', 'state', 'division', 'total_population', 'fss', 'homicide_rate',
       'firearm_homicide_rate', 'nonfirearm_homicide_rate', 'firearm_suicides',
       'total_suicides', 'firearm_homicides', 'nonfirearm_homicides',
       'total_homicides', 'white_fss', 'nonwhite_fss', 'nextyearfss',
       'nextyearnonwhitefss', 'nextyearwhitefss'],
      dtype='object')
df.dtypes
year                          int64
state                        object
division                     object
total_population            float64
fss                         float64
homicide_rate                object
firearm_homicide_rate        object
nonfirearm_homicide_rate     object
firearm_suicides              int64
total_suicides                int64
firearm_homicides           float64
nonfirearm_homicides        float64
total_homicides               int64
white_fss                   float64
nonwhite_fss                float64
nextyearfss                 float64
nextyearnonwhitefss         float64
nextyearwhitefss            float64
dtype: object
הפכנו את העמודות הדרושות לעמודות מספריות:
cols_to_convert = ['homicide_rate', 'firearm_homicide_rate', 'nonfirearm_homicide_rate']
df[cols_to_convert] = df[cols_to_convert].apply(pd.to_numeric, errors='coerce')
df.dtypes
year                          int64
state                        object
division                     object
total_population            float64
fss                         float64
homicide_rate               float64
firearm_homicide_rate       float64
nonfirearm_homicide_rate    float64
firearm_suicides              int64
total_suicides                int64
firearm_homicides           float64
nonfirearm_homicides        float64
total_homicides               int64
white_fss                   float64
nonwhite_fss                float64
nextyearfss                 float64
nextyearnonwhitefss         float64
nextyearwhitefss            float64
dtype: object
בדקנו עמודות שקיימים בהם ערכים חסרים :
df.isnull().sum()
year                          0
state                         0
division                      0
total_population              1
fss                           0
homicide_rate                 1
firearm_homicide_rate         2
nonfirearm_homicide_rate      2
firearm_suicides              0
total_suicides                0
firearm_homicides             1
nonfirearm_homicides          1
total_homicides               0
white_fss                     7
nonwhite_fss                406
nextyearfss                  52
nextyearnonwhitefss         452
nextyearwhitefss             58
dtype: int64
df.isnull().mean().sort_values(ascending=False) * 100
nextyearnonwhitefss         12.380170
nonwhite_fss                11.120241
nextyearwhitefss             1.588606
nextyearfss                  1.424267
white_fss                    0.191728
firearm_homicide_rate        0.054780
nonfirearm_homicide_rate     0.054780
total_population             0.027390
homicide_rate                0.027390
firearm_homicides            0.027390
nonfirearm_homicides         0.027390
total_homicides              0.000000
year                         0.000000
state                        0.000000
firearm_suicides             0.000000
fss                          0.000000
division                     0.000000
total_suicides               0.000000
dtype: float64
בשלב זה אנו מתמקדים בבדיקת ערכים חסרים רק בעמודות הקריטיות לניתוח: `total_population`, `firearm_homicides`, `nonfirearm_homicides`. זיהוי בעיות בעמודות אלו חשוב במיוחד מאחר שהן משמשות בהמשך לחישובי שיעורים, רגרסיות וניתוחים גאוגרפיים.
df.replace('#VALUE!', np.nan, inplace=True)

cols_to_fix = ["total_population", "firearm_homicides", "nonfirearm_homicides"]

print("Missing values after cleaning:")
print(df[cols_to_fix].isnull().sum())
Missing values after cleaning:
total_population        1
firearm_homicides       1
nonfirearm_homicides    1
dtype: int64
df[df[cols_to_fix].isnull().any(axis=1)]
year state division total_population fss homicide_rate firearm_homicide_rate nonfirearm_homicide_rate firearm_suicides total_suicides firearm_homicides nonfirearm_homicides total_homicides white_fss nonwhite_fss nextyearfss nextyearnonwhitefss nextyearwhitefss
491 1959 Alaska Pacific NaN 0.666667 NaN NaN NaN 18 27 7.0 2.0 9 0.739130 0.25 0.514286 0.0 0.562500
2587 2000 Delaware South Atlantic 783600.0 0.487805 2.935171 NaN NaN 40 82 NaN NaN 23 0.435897 NaN 0.490741 0.0 0.521277

התייחסות לערכים חסרים: במהלך הניקוי הראשוני של הנתונים, זיהינו שתי שורות עם ערכים חסרים. בשלב זה בחרנו להשאיר את שתי השורות בדאטה, תוך מודעות לכך – כדי לשקול בעתיד האם להשלים או להסיר בהתאם לצורך.

כשלב ראשון בניתוח ערכנו קיבוץ של הנתונים לפי שנה (groupby) וחישבנו את ממוצע ערכי מדד ה־FSS בכל שנה. מטרה זו נועדה לאפשר הצגה של מגמה כללית לאורך זמן – כלומר, להבין כיצד השתנתה זמינות הנשק החם בבתים ברחבי ארה"ב לאורך השנים. בהמשך לכך, יצרנו תרשים קו הממחיש את השינוי בערכי המדד לאורך השנים, במטרה לזהות מגמות ארוכות טווח.

# lihi
plt.figure(figsize=(12, 6))
sns.lineplot(data=df, x="year", y="fss")
plt.title("FSS Yearly Average Across the U.S.")
plt.xlabel("Year")
plt.ylabel("Average FSS")
plt.grid(True)
plt.show()
No description has been provided for this image
yearly_avg = df.groupby("year")["fss"].mean().reset_index()

plt.figure(figsize=(12, 6))
sns.lineplot(data=yearly_avg, x="year", y="fss")
plt.title("FSS Yearly Average Across the U.S.")
plt.xlabel("Year")
plt.ylabel("Average FSS")
plt.grid(True)
plt.show()
No description has been provided for this image
הגרף מציג בבירור מגמה של עלייה עקבית במדד עד לשנות ה־90, ולאחר מכן ירידה חדה – מה שעשוי להעיד על שינוי בדפוסי השימוש בנשק חם או בזמינותו לאורך התקופה.
נוסיף עמודה של שיעור התאבדויות כללי בכל מדינה
df['suicide_rate'] = df['total_suicides'] / df['total_population'] * 100_000
ניצור טבלת קורלציה הכוללת את שיעורי ההתאבדויות :
corr_matrix = df.corr(numeric_only=True)

plt.figure(figsize=(20, 10))
sns.heatmap(
    corr_matrix,
    cmap='PuBu',          
    center=0,            
    annot=True,            
    linewidths=4,         
    fmt=".2f"              
)

plt.title("Correlation Heatmap Between Variables", fontsize=18, fontweight='bold')
plt.xticks(rotation=45)
plt.yticks(rotation=0)
plt.tight_layout()
plt.show()
No description has been provided for this image
במפת החום ניתן לזהות קשרים חיוביים בין מדד ה־FSS (המהווה אומדן לזמינות כלי נשק) לבין שיעור הרצח הכללי (homicide_rate, r = 0.21) וכן בין מדד זה לבין שיעור ההתאבדויות הכללי (suicide_rate, r = 0.29). הקשרים הללו אמנם מתונים, אך מעוררי עניין, ולכן בהמשך הפרויקט נבחן אותם לעומק על מנת להבין האם קיימת השפעה ממשית בין רמת זמינות כלי הנשק לבין שיעורי הרצח וההתאבדויות בארצות הברית.

🔹 חלק ראשון: השפעת זמינות כלי נשק על שיעורי הרצח

בפרק זה נבחן האם קיים קשר בין זמינות כלי נשק חם, כפי שהיא נמדדת באמצעות מדד FSS, לבין שיעורי הרצח הכלליים בארה"ב לאורך השנים.

📋 מה כולל פרק זה – השפעת זמינות נשק חם על שיעור הרצח:

  • ניתוח מגמות שנתיות של מדד FSS לעומת שיעור הרצח (Homicide Rate) בארה״ב לאורך השנים (1949–2020)
  • גרף קו כפול (dual-axis line plot) המציג את התפתחות שני המדדים לאורך זמן
  • גרף פיזור שנתי עם קו מגמה – לבחינת קשר סטטיסטי ישיר בין FSS לשיעור הרצח
  • תרשים פאי המציג את כיוון הקורלציה בין המשתנים בכל שנה בנפרד (חיובי/שלילי)
  • גרף פיזור לפי מדינות – כולל השפעת המדינה החריגה District of Columbia על עוצמת הקשר
  • מסקנות מתוך כלל הגרפים – האם זמינות נשק גבוהה באמת קשורה לרמות גבוהות יותר של אלימות קטלנית
נשק בוולמארט
כצעד ראשון, יצרנו גרף תרשים קו המשווה בין מדד ה־FSS, המייצג את זמינות הנשק החם, לבין שיעור הרצח הכולל בארצות הברית. מטרת ההשוואה היא לבדוק האם קיימת מגמה משותפת בין שני המשתנים לאורך השנים. לצורך כך, חישבנו ממוצע שנתי של שני המדדים:
  • FSS – שיעור ההתאבדויות שבוצעו באמצעות נשק חם מתוך כלל ההתאבדויות.
  • Homicide Rate – שיעור מקרי הרצח לכל 100,000 נפש.

החישוב בוצע באמצעות השיטה groupby("year").mean() על מסד הנתונים, כדי לייצר מגמות חלקות וברורות לאורך זמן.

fig, ax1 = plt.subplots(figsize=(14, 6))

year_avg = df.groupby("year")[["fss", "homicide_rate"]].mean().reset_index()

color = 'tab:blue'
ax1.set_xlabel("Year")
ax1.set_ylabel("FSS (Firearm Suicide Share)", color=color)
ax1.plot(year_avg["year"], year_avg["fss"], color=color, label="FSS", linewidth=2)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()
color = 'tab:red'
ax2.set_ylabel("Homicide Rate per 100,000 people", color=color)
ax2.plot(year_avg["year"], year_avg["homicide_rate"], color=color, label="Homicide Rate", linewidth=2, linestyle='--')
ax2.tick_params(axis='y', labelcolor=color)

plt.title("Annual Trends of FSS vs. Homicide Rate in the U.S. (1949–2020)")
fig.tight_layout()
plt.grid()
plt.show()
No description has been provided for this image
התבוננות במגמות מציגה דפוס דומה בין שני המשתנים לאורך השנים – כאשר עליות וירידות במדד ה־FSS מלוות בשינויים דומים גם בשיעורי הרצח.
לאחר ניתוח המגמות השנתיות של FSS ושל שיעור הרצח, נוסיף כעת גרף פיזור (Scatter plot) שמטרתו לבחון האם קיים קשר ישיר בין שני המשתנים עצמם – כלומר, האם שנים שבהן מדד FSS גבוה יותר מאופיינות גם בשיעורי רצח גבוהים יותר.
from scipy.stats import pearsonr
r, p = pearsonr(year_avg["fss"], year_avg["homicide_rate"])

plt.figure(figsize=(10, 6))

sns.regplot(data=year_avg, x="fss", y="homicide_rate", scatter=True,
            line_kws={'color': 'red'}, scatter_kws={'s': 60})

for i, row in year_avg.iterrows():
    plt.text(row["fss"] + 0.001, row["homicide_rate"], str(int(row["year"])), fontsize=7)

plt.title(f"Total Homicide Rate vs. FSS (Yearly Averages)\n"
          f"Pearson r = {r:.2f}, p-value = {p:.4f}")
plt.xlabel("Average FSS per Year (Firearm Suicide Share)")
plt.ylabel("Average Total Homicide Rate per Year (per 100,000 people)")
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
גרף הפיזור מציג קשר חיובי חזק בין מדד ה־FSS לבין שיעור הרצח: ככל שערך ה־FSS גבוה יותר, כך גם שיעור הרצח נוטה להיות גבוה יותר. עם זאת, מאחר שמדובר בממוצעים שנתיים כלליים, נוסיף כעת גרף נוסף שיבחן את כיוון הקורלציה בכל שנה בנפרד – כדי לבדוק האם הקשר החיובי מתקיים בעקביות לאורך זמן.
yearly_corr[yearly_corr.direction == "Negative"]
year correlation direction
39 1988 -0.041666 Negative
40 1989 -0.158206 Negative
41 1990 -0.074655 Negative
42 1991 -0.056869 Negative
43 1992 -0.037399 Negative
44 1993 -0.092006 Negative
45 1994 -0.043421 Negative
46 1995 -0.008770 Negative
47 1996 -0.111352 Negative
49 1998 -0.071174 Negative
51 2000 -0.246622 Negative
55 2004 -0.217822 Negative
56 2005 -0.005058 Negative
60 2009 -0.126544 Negative
yearly_corr = (
    df[['year', 'fss', 'homicide_rate']]
    .dropna()
    .groupby('year')[['fss', 'homicide_rate']]
    .apply(lambda g: pearsonr(g['fss'], g['homicide_rate'])[0])
    .reset_index(name='correlation')
)

yearly_corr['direction'] = yearly_corr['correlation'].apply(
    lambda r: 'Positive' if r > 0 else 'Negative'
)

yearly_direction_counts = yearly_corr['direction'].value_counts()

colors = ['#003366', '#66b2ff'] 
plt.figure(figsize=(4, 6))
plt.pie(
    yearly_direction_counts,
    labels=yearly_direction_counts.index,
    autopct='%1.1f%%',
    startangle=90,
    colors=colors
)
plt.title('Correlation Direction Between FSS and Homicide Rate by Year')
plt.tight_layout()
plt.show()
No description has been provided for this image
התרשים מדגים כי ברוב המוחלט של השנים (כ־80%) הקשר בין מדד ה־FSS לבין שיעור הרצח היה חיובי – כלומר, ככל שזמינות הנשק הייתה גבוהה יותר, כך גם נרשמו שיעורי רצח גבוהים יותר.
עם זאת, כל הגרפים עד כה הציגו קשרים לאורך זמן (Across Years). כעת נפנה לבחינה גאוגרפית – נבדוק האם מדינות שבהן ה־FSS גבוה יותר נוטות להציג גם שיעורי רצח גבוהים מהממוצע.
df_state_clean = df[['state', 'fss', 'homicide_rate']].dropna()

state_avg = df_state_clean.groupby('state')[['fss', 'homicide_rate']].mean().reset_index()

fig = px.scatter(
    state_avg,
    x="fss",
    y="homicide_rate",
    hover_name="state",
    opacity=0.6,  
    labels={
        "fss": "Average FSS per State",
        "homicide_rate": "Homicide Rate (per 100,000)"
    },
    title="Homicide Rate vs. FSS by State"
)

slope, intercept, r_value, p_value, *_ = linregress(state_avg["fss"], state_avg["homicide_rate"])
x_vals = state_avg["fss"].sort_values()
y_vals = intercept + slope * x_vals
fig.add_scatter(x=x_vals, y=y_vals, mode='lines', name=f"Trendline (r = {r_value:.2f}, p = {p_value:.4f})", line=dict(color='red'))
fig.update_layout(
    width=1000,
    height=500
)
ניתן לראות כי קיימת מדינה אחת חריגה (outlier) בעלת שיעור רצח גבוה במיוחד יחסית לשאר המדינות, ואשר בולטת כלפי מעלה בגרף. מדינה זו היא District of Columbia, אשר מאופיינת באוכלוסייה עירונית צפופה ובמאפיינים חברתיים-פוליטיים חריגים, ולכן אינה מייצגת את דפוסי שאר המדינות. מסיבה זו, היא תוסר בניתוח הבא על מנת לא לעוות את קו המגמה או את מדדי הקשר הסטטיסטיים
df_state_clean = df[['state', 'fss', 'homicide_rate']].dropna()
df_state_clean = df_state_clean[df_state_clean['state'] != 'District of Columbia']

state_avg = df_state_clean.groupby('state')[['fss', 'homicide_rate']].mean().reset_index()

fig = px.scatter(
    state_avg,
    x="fss",
    y="homicide_rate",
    hover_name="state",
    opacity=0.6,  
    labels={
        "fss": "Average FSS per State",
        "homicide_rate": "Homicide Rate (per 100,000)"
    },
    title="Homicide Rate vs. FSS by State"
)

slope, intercept, r_value, p_value, *_ = linregress(state_avg["fss"], state_avg["homicide_rate"])
x_vals = state_avg["fss"].sort_values()
y_vals = intercept + slope * x_vals
fig.add_scatter(x=x_vals, y=y_vals, mode='lines', name=f"Trendline (r = {r_value:.2f}, p = {p_value:.4f})", line=dict(color='red'))
fig.update_layout(
    width=1000,
    height=500
)
fig.show()
לאחר שהסרנו את המדינה החריגה District of Columbia, ניתן לראות כי נחשפת קורלציה חזקה וקשר מובהק בין מדד ה־FSS לבין שיעור מקרי הרצח – כך שמדינות עם זמינות נשק גבוהה יותר מציגות גם שיעורי רצח גבוהים יותר.
📌 לסיכום:
מכלול הגרפים והניתוחים שבוצעו בפרק זה מצביע על קשר עקבי ומשמעותי בין זמינות כלי נשק חם – כפי שנמדדת במדד ה־FSS – לבין שיעור מקרי הרצח בארצות הברית.
ניתוח מגמות לאורך השנים הראה כי תקופות של עלייה ב־FSS מלוות גם בעלייה חדה בשיעורי הרצח, ולהפך.
גרף הפיזור השנתי הדגים קשר חיובי חזק (r = 0.85), ותרשים הפאי הראה כי בכ־80% מהשנים הקשר היה חיובי, דבר שמחזק את עקביות הקשר לאורך זמן.
גם ברמה הגאוגרפית, כאשר בחנו את הקשר בין FSS לשיעורי הרצח לפי מדינות, התקבלה מגמת עלייה – ובפרט לאחר הסרת המדינה החריגה District of Columbia, נחשפה קורלציה מובהקת בין המשתנים (r = 0.52).

לסיכום, הנתונים מחזקים את ההשערה לפיה זמינות גבוהה של כלי נשק עשויה לתרום לעלייה באלימות קטלנית – לא רק מבחינה תאורטית, אלא גם באופן מובהק סטטיסטית לאורך זמן ובחתכים גאוגרפיים.

🔹חלק שני: הקשר בין כלי נשק לשיעורי התאבדות

בפרק זה נבחן האם קיים קשר בין זמינות כלי נשק חם (FSS – שיעור ההתאבדויות שנעשו בנשק חם מתוך כלל ההתאבדויות) לבין שיעורי ההתאבדות הכלליים, הן מבחינת השוואה גיאוגרפית והן מבחינת מגמות לאורך השנים.

📑 מה כולל פרק זה – השפעת זמינות נשק חם על שיעור ההתאבדות:

  • גרף קו (Line plot): השוואה בין ממוצע FSS לממוצע שיעור התאבדות לאורך זמן (1949–2020)
  • גרף פיזור עם קו מגמה (Scatter plot): לבדיקת קשר בין זמינות כלי נשק לשיעור התאבדויות
  • חישוב מקדם מתאם פיארסון והצגת משמעות סטטיסטית
  • ניתוח ממוצע לפי מדינה: השוואה בין ממוצע מדד FSS לבין שיעור ההתאבדות הכללי לכל מדינה
  • מסקנות מתוך ניתוח הגרפים – האם קיים קשר בין זמינות נשק לבין רמת ההתאבדות במדינה ובמהלך הזמן?
תמונה חלק 2
כמו בפרק הקודם, נתחיל בבחינת המגמות ההיסטוריות – הפעם של מדד ה־FSS (שיעור ההתאבדויות שבוצעו בנשק חם) לעומת שיעור ההתאבדות הכללי לאורך השנים (1949–2020). המטרה היא לזהות האם קיימת מגמה משותפת בין זמינות נשק חם לבין שיעורי ההתאבדות בארצות הברית.
summary = df.groupby('year').agg({
    'fss': 'mean',
    'suicide_rate': 'mean'
}).reset_index()

fig, ax1 = plt.subplots(figsize=(14, 6))

color1 = 'tab:blue'
ax1.set_xlabel('Year')
ax1.set_ylabel('FSS (Firearm Suicide Share)', color=color1)
ax1.plot(summary['year'], summary['fss'], color=color1, marker='o', label='FSS')
ax1.tick_params(axis='y', labelcolor=color1)

ax2 = ax1.twinx()
color2 = 'tab:green'
ax2.set_ylabel('Suicide Rate (per 100,000)', color=color2)
ax2.plot(summary['year'], summary['suicide_rate'], color=color2, marker='s', linestyle='--', label='Suicide Rate')
ax2.tick_params(axis='y', labelcolor=color2)

lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines1 + lines2, labels1 + labels2, loc='upper left')

plt.title("FSS vs. Suicide Rate Over Time")
fig.tight_layout()
plt.show()
No description has been provided for this image
מהגרף המוצג ניתן להסיק כי לא מתקיים קשר עקבי וחזק בין מדד ה־FSS לבין שיעור ההתאבדויות הכללי לאורך השנים.
בין שנות ה־60 לשנות ה־90 נראית מגמה מקבילה – עלייה במדד ה־FSS מלווה גם בעלייה בשיעור ההתאבדויות. עם זאת, החל משנות ה־2000 התמונה משתנה: בעוד ששיעור ההתאבדויות הכללי ממשיך לעלות, מדד ה־FSS דווקא מציג ירידה חדה.

תצפית זו מרמזת כי רמות אחזקת הנשק (כפי שמשתקפות במדד ה־FSS) אינן בהכרח משפיעות על שיעור ההתאבדויות הכללי, אלא בעיקר על אופן ביצוע ההתאבדות – כלומר, האם ההתאבדות מתבצעת באמצעות נשק חם או לא.

מכאן עולה השאלה הבאה: גם אם שיעור ההתאבדות הכללי אינו תלוי ישירות בזמינות כלי נשק, האם ייתכן שזמינות גבוהה יותר של נשק (FSS גבוה) מובילה בפועל ליותר התאבדויות?

לשם כך, נבחן כעת את הקשר בין שני המשתנים ברמת המדינה – ונבדוק האם מדינות שבהן מדד ה־FSS גבוה יותר מציגות גם שיעור התאבדות כללי גבוה יותר.
df_clean = df[['state', 'fss', 'suicide_rate']].dropna()

state_avg = df_clean.groupby('state')[['fss', 'suicide_rate']].mean().reset_index()

r, p = pearsonr(state_avg['fss'], state_avg['suicide_rate'])

plt.figure(figsize=(10, 6))
sns.regplot(data=state_avg, x='fss', y='suicide_rate')

for i, row in state_avg.iterrows():
    plt.text(row['fss'] + 0.002, row['suicide_rate'], row['state'], fontsize=7)

plt.title(f'Correlation Between FSS and Suicide Rate\nPearson r = {r:.2f}, p = {p:.4f}')
plt.xlabel('Average FSS (Firearm Suicide Share)')
plt.ylabel('Average Suicide Rate (per 100,000)')
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
הגרף מראה כי אכן קיים קשר חיובי בין זמינות נשק חם (FSS) לבין שיעור ההתאבדות הכללי – עם מקדם מתאם בינוני אך מובהק סטטיסטית (r = 0.47, p = 0.0005). כלומר, מדינות שבהן שיעור ההתאבדויות שבוצעו בנשק חם גבוה יותר, נוטות גם להציג שיעור התאבדות כללי גבוה יותר.
לצד ניתוח הקורלציה הכולל, חשוב לבחון האם קיימים הבדלים משמעותיים בין קבוצות מדינות – כלומר, האם שיעור ההתאבדות הכללי אכן גבוה יותר במדינות בהן מדד ה־FSS גבוה מהחציון, לעומת מדינות בהן הוא נמוך מהחציון. לשם כך נבצע השוואה באמצעות תרשים Boxplot בין שתי קבוצות: מדינות עם FSS גבוה מהחציון לעומת מדינות עם FSS נמוך ממנו.
threshold = state_avg['fss'].median()

state_avg['FSS_Level'] = state_avg['fss'].apply(lambda x: 'High FSS' if x > threshold else 'Low FSS')

custom_palette = {'High FSS': '#003366', 'Low FSS': '#66b2ff'}

plt.figure(figsize=(8, 6))
sns.boxplot(data=state_avg, x='FSS_Level', y='suicide_rate', hue='FSS_Level', palette=custom_palette, legend=False)
plt.title('Comparison of Suicide Rates by FSS Level (High vs Low)')
plt.ylabel('Average Suicide Rate (per 100,000)')
plt.xlabel('FSS Level')
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
מתרשים ה־Boxplot ניתן לראות כי מדינות שבהן מדד ה־FSS גבוה מהחציון נוטות להציג שיעור התאבדות כללי גבוה יותר, בהשוואה למדינות בעלות FSS נמוך מהחציון. ממצא זה מחזק את ההשערה לפיה זמינות גבוהה של נשק חם עשויה להגביר את הסיכון למקרי התאבדות.
📌 לסיכום:
מהניתוחים שבוצעו בפרק זה עולה כי קיים קשר חיובי בין מדד ה־FSS – המציג מדד עקיף לשיעור אחזקת הנשק בבתים – לבין שיעור ההתאבדויות הכללי.
ממצא זה בלט במיוחד ברמה ההשוואתית בין מדינות: מדינות שבהן מדד ה־FSS גבוה מהממוצע נוטות להציג גם שיעורי התאבדות כלליים גבוהים יותר.
גרף הפיזור חישב מקדם מתאם בינוני אך מובהק סטטיסטית (r = 0.47, p = 0.0005), ובתרשים ה־Boxplot זוהה הבדל מהותי בין שתי קבוצות – מדינות עם FSS גבוה לעומת כאלה עם FSS נמוך – מבחינת שיעור ההתאבדות הממוצע.
עם זאת, ניתוח המגמות לאורך השנים הראה כי הקשר אינו עקבי בכל תקופה, וקיימות גם מדינות חריגות או נתונים חלקיים שממתנים את עוצמת המסקנה. לכן, למרות שיש אינדיקציות ברורות לכך שנשק חם תורם לעלייה בפועל בשיעור ההתאבדויות, קשה להצביע עליו כעל הגורם המרכזי.

לסיכום, הנתונים שנאספו אינם מצביעים על כך שנשק חם הוא הגורם הישיר להתאבדות, אך כן תומכים בטענה שלזמינותו השפעה מהותית: כאשר כלי נשק חם נגיש וזמין – שיעור ההתאבדויות בפועל נוטה להיות גבוה יותר.


🔹חלק שלישי: שונות גיאוגרפית – איפה הכי בטוח לחיות

בחלק זה נרצה להשוות בין האזורים השונים והמדינות השונות בארצות הברית, מבחינת רמת הבטיחות שלהן – וזאת על ידי בחינת כמות מקרי הרצח המדווחים בכל אחת מהן לאורך השנים. מטרת ההשוואה היא לזהות דפוסים גיאוגרפיים של אלימות קטלנית, ולהבין אילו אזורים מאופיינים ברמות סיכון גבוהות יותר לעומת אחרים.

📑 מה כולל פרק זה – שונות גיאוגרפית: איפה הכי בטוח לחיות?

  • השוואת ממוצע שיעור הרצח הכללי בכל אחד מהאזורים (Divisions) בארה"ב
  • ניתוח התפלגות פנימית בתוך כל אזור – באמצעות תרשימי Boxplot
  • השוואה בין מדינות בתוך כל Division: גרף עמודות אופקי לפי צבע נורמליזציה
  • תחזית לעתיד: חיזוי שיעור הרצח הכללי לכל מדינה לשנים 2025–2030 באמצעות רגרסיה ליניארית
  • מפת חום אינטראקטיבית של שיעור הרצח (2000–2030): סקירת מגמות עתידיות לפי מדינה
No description has been provided for this image
ראשית, נרצה להשוות בין האזורים השונים בארצות הברית מבחינת רמת האלימות, על ידי בחינת ממוצע שיעור הרצח הכללי בכל אזור (Division) לאורך השנים, על מנת להבין אילו אזורים נחשבים לבטוחים יותר מבחינה סטטיסטית.
division_avg = df.groupby('division', as_index=False)['homicide_rate'].mean()

division_sorted = division_avg.sort_values('homicide_rate')

plt.figure(figsize=(8, 6))
sns.barplot(
    x='homicide_rate',
    y='division',
    data=division_sorted,
    palette='RdYlBu_r',
    hue='division',     
    legend=False         
)

plt.title('Average Total Homicide Rate by Division (1949–2020)', fontsize=14)
plt.xlabel('Homicide Rate (per 100,000 people)')
plt.ylabel('U.S. Census Division')
plt.tight_layout()
plt.show()
No description has been provided for this image
לאחר שזיהינו פערים בין האזורים השונים בארצות הברית מבחינת שיעור הרצח, נרצה לבחון האם קיימת גם התפלגות פנימית משמעותית בתוך כל אזור (Division) – כלומר, עד כמה המדינות בתוך כל אזור שונות זו מזו מבחינת רמות האלימות הקטלנית.
state_division_avg = df.groupby(['state', 'division'], as_index=False)['homicide_rate'].mean()

plt.figure(figsize=(12, 6))
sns.boxplot(data=state_division_avg, 
            x='homicide_rate', 
            y='division', 
            hue='division',        
            palette='RdYlBu_r',
            legend=False)          

plt.title('Distribution of Total Homicide Rates Within Each Division', fontsize=14)
plt.xlabel('Total Homicide Rate (per 100,000 people)')
plt.ylabel('U.S. Census Division')
plt.tight_layout()
plt.show()
No description has been provided for this image

מהגרף ניתן לראות כי קיימת שונות פנימית בין המדינות השייכות לאותו אזור (Division). לדוגמה, באזורים כמו East South Central ו־Pacific נצפים פערים גדולים בין המדינות – חלקן בעלות שיעור רצח גבוה במיוחד, ואחרות נמוכות בהרבה.

לכן, אזור שנחשב למסוכן בממוצע עשוי להכיל גם מדינות בטוחות יחסית – ולהפך. חשוב להתבונן גם בפיזור הפנימי בתוך כל אזור, ולא רק בממוצע הכללי. לשם כך יצרנו גרף מסוג FacetGrid, המציג עבור כל אזור גרף עמודות אופקי (horizontal bar chart) שבו כל עמוד מייצג מדינה והשיעור הממוצע של מקרי הרצח בה. הגרפים צבועים בסקאלת צבעים אחידה לפי מדרג ארצי, כך שניתן לזהות במהירות אילו מדינות בולטות לרעה או לטובה בתוך ההקשר האזורי שלהן.

norm = Normalize(vmin=state_division_avg['homicide_rate'].min(),
                 vmax=state_division_avg['homicide_rate'].max())
cmap = plt.get_cmap('RdYlBu_r')
state_division_avg['color'] = state_division_avg['homicide_rate'].apply(lambda x: to_hex(cmap(norm(x))))

division_order = (
    state_division_avg.groupby('division')['homicide_rate']
    .mean()
    .sort_values()
    .index
    .tolist()
)

def colored_barplot_local_xaxis(data, **kwargs):
    data = data.sort_values('homicide_rate')
    ax = plt.gca()
    for i, row in enumerate(data.itertuples()):
        ax.barh(y=i, width=row.homicide_rate, color=row.color)
    ax.set_yticks(range(len(data)))
    ax.set_yticklabels(data['state'])
    ax.invert_yaxis()

g = sns.FacetGrid(state_division_avg, 
                  col='division', 
                  col_wrap=3, 
                  height=4, 
                  sharex=False, 
                  sharey=False,
                  col_order=division_order)

g.map_dataframe(colored_barplot_local_xaxis)
g.set_axis_labels('Total Homicide Rate', 'State')
g.set_titles('{col_name}')
plt.subplots_adjust(top=0.9)
g.fig.suptitle('Total Homicide Rate by State Within Each Division', fontsize=14)

sm = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = g.fig.colorbar(sm, ax=g.axes, shrink=0.6, location='right')
cbar.set_label('Homicide Rate (per 100k people)')

plt.show()
No description has been provided for this image
כעת נרצה להציג תחזית אינטראקטיבית של שיעור הרצח הכללי (לכל 100,000 איש) בכל מדינה בארצות הברית, בין השנים 2000 ל־2030. תחזית זו מבוססת על מגמות שנצפו בעבר, תוך שימוש במודל רגרסיה ליניארית לחיזוי הערכים העתידיים לשנים 2025–2030. המטרה היא לבחון את רמת הבטיחות הכללית של המדינות השונות לאורך זמן, כלומר ניתוח מקיף של כלל מקרי הרצח. מידע זה עשוי לסייע בזיהוי מגמות רחבות של אלימות פלילית, ובחינה של אזורים שנחשבים לבטוחים יותר למגורים בטווח הארוך.
df.columns = df.columns.str.strip().str.replace(' ', '_')
df['homicide_rate'] = pd.to_numeric(df['homicide_rate'], errors='coerce')

df = df[df['year'] >= 2000].dropna(subset=['homicide_rate'])

years_to_predict = list(range(2025, 2031))
predictions = []

for state in df['state'].unique():
    state_data = df[df['state'] == state]
    if len(state_data) < 5:
        continue
    X = state_data[['year']]
    y = state_data['homicide_rate']
    model = LinearRegression().fit(X, y)

    for year in years_to_predict:
        pred = model.predict(pd.DataFrame({'year': [year]}))[0]
        predictions.append({
            'state': state,
            'year': year,
            'homicide_rate': pred
        })

future_df = pd.DataFrame(predictions)

df_anim = pd.concat([df[['state', 'year', 'homicide_rate']], future_df], ignore_index=True)

state_abbrev = {
    'Alabama': 'AL', 'Alaska': 'AK', 'Arizona': 'AZ', 'Arkansas': 'AR',
    'California': 'CA', 'Colorado': 'CO', 'Connecticut': 'CT', 'Delaware': 'DE',
    'Florida': 'FL', 'Georgia': 'GA', 'Hawaii': 'HI', 'Idaho': 'ID',
    'Illinois': 'IL', 'Indiana': 'IN', 'Iowa': 'IA', 'Kansas': 'KS',
    'Kentucky': 'KY', 'Louisiana': 'LA', 'Maine': 'ME', 'Maryland': 'MD',
    'Massachusetts': 'MA', 'Michigan': 'MI', 'Minnesota': 'MN', 'Mississippi': 'MS',
    'Missouri': 'MO', 'Montana': 'MT', 'Nebraska': 'NE', 'Nevada': 'NV',
    'New Hampshire': 'NH', 'New Jersey': 'NJ', 'New Mexico': 'NM', 'New York': 'NY',
    'North Carolina': 'NC', 'North Dakota': 'ND', 'Ohio': 'OH', 'Oklahoma': 'OK',
    'Oregon': 'OR', 'Pennsylvania': 'PA', 'Rhode Island': 'RI', 'South Carolina': 'SC',
    'South Dakota': 'SD', 'Tennessee': 'TN', 'Texas': 'TX', 'Utah': 'UT',
    'Vermont': 'VT', 'Virginia': 'VA', 'Washington': 'WA', 'West Virginia': 'WV',
    'Wisconsin': 'WI', 'Wyoming': 'WY', 'District of Columbia': 'DC'
}
df_anim['state_code'] = df_anim['state'].map(state_abbrev)

fig = px.choropleth(
    df_anim,
    locations='state_code',
    locationmode='USA-states',
    color='homicide_rate',
    hover_name='state',
    animation_frame='year',
    scope='usa',
    color_continuous_scale='Reds',
    range_color=(0, 25),
    labels={'homicide_rate': 'Total Homicide Rate (per 100k)'},
    title='Total Homicide Rate by State (2000–2030 including forecast)'
)

fig.update_layout(
    geo=dict(bgcolor='rgba(0,0,0,0)'),
    width=1000,
    height=600
)

fig.show()

תחזית לשנים 2025–2030 מציגה שמדינות עם שיעורי רצח גבוהים לאורך השנים, כמו Louisiana ו־Mississippi, צפויות לשמור על מגמה דומה גם בעתיד.
לעומתן, מדינות עם שיעורים נמוכים בעבר, כמו Maine ו־Vermont, מציגות תחזית יציבה ונמוכה.

📌 לסיכום:

מהניתוחים שבוצעו בפרק זה עולה כי קיימים פערים גאוגרפיים עקביים ומשמעותיים בשיעורי הרצח בארה"ב, הן בין אזורים (Divisions) והן בין מדינות בודדות.
ממוצעי שיעורי הרצח לפי אזורים הצביעו על כך שאזורים כמו New England ו־West North Central מציגים רמות נמוכות לאורך שנים, בעוד East South Central ו־South Atlantic בולטים ברמות גבוהות במיוחד.
תרשימי Boxplot הדגישו את הפערים הפנימיים בתוך כל Division, והראו שונות רבה בין המדינות המרכיבות אותו.
בניתוח לפי מדינות, נמצא שמדינות כמו Mississippi ו־Louisiana שמרו על שיעורי רצח גבוהים בעקביות, לעומת Maine ו־New Hampshire שהציגו רמות יציבות ונמוכות לאורך זמן.
תחזית עתידית לשנים 2025–2030, שבוצעה באמצעות רגרסיה ליניארית, חיזקה את הממצאים: גם בעתיד הקרוב הפערים צפויים להישמר, ואף להתרחב בחלק מהמדינות.

לסיכום, הנתונים שנאספו מחזקים את הטענה: השונות הגאוגרפית בשיעורי הרצח בארצות הברית היא עמוקה, יציבה ומתמשכת – וניכרת הן בתחזיות עבר והן בתחזיות עתידיות.

סיכום הפרויקט

בעוד שהפרויקט אינו קובע סיבתיות, הוא מספק עדויות ברורות לכך שזמינות נשק חם היא משתנה מרכזי המשפיע על רמות האלימות בחברה האמריקאית. המתאם עם שיעורי רצח מובהק, והקשר להתאבדויות מרמז על השלכות פוטנציאליות של מדיניות רישוי ואחזקת נשק.

לסיכום: זמינות נשק חם אינה רק עניין אישי או פוליטי – היא גורם חברתי המשפיע באופן ישיר על בטיחות הציבור.